﻿using FyCaches.Core.Services;
using FySystem.AssistantServices;
using FySystem.Configuration;
using FySystem.FyAppConfig;
using FySystem.IOTFlow;
using FySystem.Net.SimSocket;
using System;
using System.Collections.Generic;
using System.Net;
using System.Text;

namespace FyCaches
{
    /// <summary>
    /// 权限控制：将账号和密码通过MD5加密后传入服务端，服务端启动时自动将账号和密码预先按照MD5加密，
    /// 每次客户端发起请求时，都在前面36字节中添加MD5加密字符串
    /// 0-35：账号密码加密字符串
    /// 36-39：指令
    /// 40-41：KEY长度
    /// 42-42+Len-1：KEY
    /// 42+LEN：Value
    /// </summary>
    class Program
    {
        static void Main(string[] args)
        {
            IAssistantServiceContext assistantServiceContext = AssistantServiceContext.CreateService(30, false);

            //初始化网络服务（用这个来作为网络连接，似乎效率有点低，不过以后可以扩展一个缓存打包解包专用版本，目前用的是MsgHandlerV1）
            assistantServiceContext.AddService<SimServer>("sev").Configure(service =>
            {
                SimServer server = (SimServer)service;
                server.IpAddress = IPAddress.Any;
                server.Port = int.Parse(FyAppConfigManager.Appconfigs["port"]);
                server.OnAccept = OnAccept;
                server.OnException = OnException;
                server.OnReceive = OnReceive;
                server.OnConnectionGC = MessageService.GC;
            });

            Console.WriteLine("*****************************************************");
            Console.WriteLine("*****************    FyCaches     *******************");
            Console.WriteLine("***************** Tianshanzhuyuan *******************");
            Console.WriteLine("*****************************************************");
            Console.WriteLine($"说明：[{FyAppConfigManager.Appconfigs["port"]}]");
            Console.WriteLine("比较简陋的Key-Value缓存数据集，目前只能单机模式，并且程序重启数据丢失");
            Console.WriteLine("制作它的原因是新版Redis放弃了Windows，但有时候做项目又很难离开Windows，");
            Console.WriteLine("对于一些不是很大的项目租两个服务器又太奢侈。");
            Console.WriteLine("=====================================================");
            Console.WriteLine("使用C#与.net开发");
            Console.WriteLine("效率不是那么的高，仅针对中小型项目");

            //初始化用户认证
            AuthService.Init();

            assistantServiceContext.Run();

            /* 10个缓存数据集，创建10个线程，每个线程管理一个数据集，对同一个数据集的操作是单线程的，
             * 所以不需要对内存变量进行锁操作
             * */
            for(int i = 0; i < 10; i++)
            {
                CacheFlowService.CacheFlows[i] = new WorkFlow<Models.CommandInfo>(CacheFlowService.Handle);
                CacheFlowService.Caches[i] = new Dictionary<string, byte[]>();
            }

            Console.WriteLine("启动成功~");

            while (true)
            {
                Console.ReadKey();
            }
        }

        private static void OnReceive(SimClient simClient, FrameInfo frame)
        {
            try
            {
                CommandService.HandleMsgs(simClient, frame);
            }
            catch (Exception ex)
            {
                FyLogContext.Write(ex.Message);
            }
        }

        private static void OnException(Exception ex, SimClient simClient)
        {
            FyLogContext.Write(ex.Message);
        }

        private static void OnAccept(SimClient simClient)
        {
            //Console.WriteLine("新连接连入");
        }
    }
}
